# -*- coding: utf-8 -*-

import json
import com.maycur.gateway.common.locust_global as the_g

from enum import Enum
from locust import SequentialTaskSet, TaskSet
from locust.contrib.fasthttp import FastResponse, FastHttpUser
from typing import Any


class EnvMapping:
    # App host
    app_host: str
    # Boss host
    auth_host: str

    def __init__(self, app_host, auth_host):
        self.app_host = app_host
        self.auth_host = auth_host


class EnvInfo(Enum):
    NG_SIT = EnvMapping('https://ng-sit.maycur.com', 'https://auth-uat.maycur.com')
    NG_UAT = EnvMapping('https://ng-uat.maycur.com', 'https://auth-uat.maycur.com')
    NG_PROD = EnvMapping('https://ng.maycur.com', 'https://auth.maycur.com')
    DT_SIT = EnvMapping('https://dt-sit.maycur.com', 'https://auth-uat.maycur.com')
    DT_UAT = EnvMapping('https://dt-uat.maycur.com', 'https://auth-uat.maycur.com')
    DT_PROD = EnvMapping('https://dt.maycur.com', 'https://auth.maycur.com')
    NG_DEV4 = EnvMapping('https://ng-dev4.maycur.com', 'https://auth-dev.maycur.com')


class ApiType(Enum):
    OPEN_API = 'OPEN_API'
    WEB_API = 'WEB_API'


class ApiOrgInfo:
    select_ent_code: str = ''
    token_id: str = ''


class OpenApiOrgInfo(ApiOrgInfo):
    org_name = ''
    app_code = ''
    app_secret = ''


class MaycurWebUser:
    user_name: str
    phone_number: str
    password: str
    default_ent_code: str
    select_ent_code: str
    token_id: str


class ResultDto:
    """
    请求的响应结果
    """
    code: str
    biz_code: str
    message: str
    data: Any


class CommonTaskSet:
    env: EnvInfo
    org_info: ApiOrgInfo
    name: str

    def get_env(self):
        if self.env is None:
            self.env = the_g.env
        return self.env

    def get_app_host(self):
        env = self.get_env()
        return env.value.app_host

    @staticmethod
    def parse_response(response: FastResponse) -> ResultDto:
        if response.status_code == 200:
            res_json = json.loads(response.text)
            result_dto = ResultDto()
            try:
                result_dto.code = res_json['code']
            except KeyError:
                # 未按照统一格式返回，直接将结果作为ResultDto的data
                result_dto.data = res_json
                return result_dto
            result_dto.message = res_json['message']
            result_dto.data = res_json['data']
            try:
                result_dto.biz_code = res_json['bizCode']
            except KeyError:
                pass

            if result_dto is not None and result_dto.code != 'ACK':
                response.failure(f'failed, result_dto code is {result_dto.code}, reason is {result_dto.message}')
            return result_dto
        else:
            print(f'failed, response status is {response.status_code}')
            response.failure(f'failed, response status is {response.status_code}')


class SequentialApiTaskSet(CommonTaskSet, SequentialTaskSet):
    """
    该任务集下的多个任务按顺序执行
    """
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.env = None
        self.org_info = None
        self.weight = 1

    def get_headers(self):
        return {
            "entCode": self.user.select_ent_code,
            "tokenId": self.user.token_id
        }

    def get_headers_with_content_type(self):
        headers = self.get_headers()
        headers['Content-Type'] = 'application/json'
        return headers


class ApiTaskSet(CommonTaskSet, TaskSet):
    """
    该任务集下的多个任务按权重随机执行
    """
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.env = None
        self.org_info = None

    def get_headers(self):
        return {
            "entCode": self.user.select_ent_code,
            "tokenId": self.user.token_id
        }

    def get_headers_with_content_type(self):
        headers = self.get_headers()
        headers['Content-Type'] = 'application/json'
        return headers
